﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Sl.Support.McuBytes {
	internal static class Byte_Expand {
		/// <summary>将单个byte转换为HEX字符串。</summary>
		internal static string toHexStr(this byte b) {
			char[] ca = new char[2];
			ca[0] = (char)(b / 16);
			if (ca[0] > 9) {
				ca[0] += (char)('A' - 10);
			} else {
				ca[0] += '0';
			}
			ca[1] = (char)(b % 16);
			if (ca[1] > 9) {
				ca[1] += (char)('A' - 10);
			} else {
				ca[1] += '0';
			}
			return new string(ca, 0, 2);
		}
		/// <summary>将int作为8位的单个byte转换为HEX字符串，将忽略其他位。</summary>
		internal static string AsByteToHexSt(this int i) {
			byte b = (byte)i;
			return b.toHexStr();
		}
		/// <summary>将比特数组转换为字符串</summary>
		internal static string toHexStr(this byte[] ba, int len = -1) {
			if (ba == null) {
				return "<null>";
			}
			if (len == -1) {
				len = ba.Length;
			}
			if (len == 0) {
				return "<empty>";
			}
			char[] ca = new char[len * 3];
			int p = 0;
			void add(int b) {
				ca[p] = (char)(b % 16);
				if (ca[p] > 9) {
					ca[p] += (char)('A' - 10);
				} else {
					ca[p] += '0';
				}
				p++;
			}
			for (int i = 0; i < len; i++) {
				add(ba[i] >> 4);
				add(ba[i]);
				ca[p] = ' ';
				p++;
			}
			return new string(ca);
		}
		static internal string toHexStr(this byte[] ba, int bgn, int len) {
			if (ba == null) {
				return "<null>";
			}
			if (len == 0) {
				return "<empty>";
			}
			char[] ca = new char[len * 3];
			int p = 0;
			void add(int b) {
				ca[p] = (char)(b % 16);
				if (ca[p] > 9) {
					ca[p] += (char)('A' - 10);
				} else {
					ca[p] += '0';
				}
				p++;
			}
			for (int i = 0; i < len; i++) {
				add(ba[i + bgn] >> 4);
				add(ba[i + bgn]);
				ca[p] = ' ';
				p++;
			}
			return new string(ca);
		}


		/// <summary>取得比特的某一位作为布尔。</summary>
		internal static bool bit(this byte b, int diff) {
			return (b & (1 << diff)) != 0;
		}
		/// <summary>将布尔值写入比特的特定一位</summary>
		internal static byte writeBit(ref this byte b, int diff, bool value) {
			if (value)
				b |= (byte)(1 << diff);
			else
				b &= (byte)~(1 << diff);
			return b;
		}
		/// <summary>将byte作为有符号数转变为int</summary>
		internal static int asSigned(this byte b) {
			int rev = b;
			if (rev > 127) {
				rev -= 256;
			}
			return rev;
		}

		/// <summary>将符合C语言规范的比特数组转换为字符串</summary>
		internal static byte[] ToByteAsCArroy(this string st, out string error) {
			// TODO:
			//change inpot 0x
			int begin = st.IndexOf('{');
			int end = st.IndexOf('}');
			if (begin < 0) {
				error = "Miss char '{'";
				return null;
			}
			if (end < 0) {
				error = "Miss char '}'";
				return null;
			}
			if (end <= begin) {
				error = "No arror {...}";
				return null;

			}
			st = st.Substring(begin + 1, end - begin - 1);
			st = st.Replace(" ", "").Replace(";", "").Replace("\n", "").Replace("\r", "").Replace("\t", "");
			string[] sta = st.Split(',');
			byte[] b = new byte[sta.Length];
			for (int i = 0; i < sta.Length; i++) {//调试错误 这里应该处理空数组
				if (sta[i].Length == 0) {
					error = "Number " + i + " is missing";
					return null;
				}
				int provider;
				if ((sta[i].ToCharArray()[0] == '0') && (sta[i].Length > 1)) {
					if (sta[i].ToCharArray()[1] == 'x') {
						provider = 16;
						sta[i] = sta[i].Substring(2);
					} else {
						provider = 8;
						sta[i] = sta[i].Substring(1);
					}
				} else {
					provider = 10;
				}
				try {
					b[i] = System.Convert.ToByte(sta[i], provider);
				} catch {
					error = "\"" + sta[i] + "\"" + " is not a number";
					return null;
				}
			}
			error = "done";
			return b;
		}

		internal static byte asHexToByte(this string st, int from = 0) {
			char[] ca = st.ToCharArray(from, 2);
			return (byte)(asHexToByte(ca[1]) | ((asHexToByte(ca[0]) << 4)));
		}
		internal static byte asHexToByte(char ca) {
			byte b = 0;
			if ((ca >= '0') && (ca <= '9')) {
				b = (byte)((int)ca - (int)'0');
			} else if ((ca >= 'A') && (ca <= 'F')) {
				b = (byte)((int)ca - (int)'A' + 10);
			} else if ((ca >= 'a') && (ca <= 'f')) {
				b = (byte)((int)ca - (int)'a' + 10);
			} else {
				throw new Exception("Hex bad char '" + ca + "'(" + (int)ca + ")");
			}
			return b;
		}
		internal static int bits(this byte b, int from, int len) {
			return (b>>from)&(~(0xff<<len));
		}
	}
}
